/**************************************************************************************************
* Title: RenderManager.cpp
* Authors: Gael Huber, Erin Mooney
* Description: Manages OpenGL rendering pipeline.
**************************************************************************************************/
#include "SmurfsRenderManager.h"

// Singleton instance
template<> RenderManager* Singleton<RenderManager>::singleton = 0;

/**************************************************************************************************
* Constructor
**************************************************************************************************/
RenderManager::RenderManager(void) {
	// Do nothing
}

/**************************************************************************************************
* Destructor
**************************************************************************************************/
RenderManager::~RenderManager(void) {
	// Do nothing
}

/**************************************************************************************************
* Initialize OpenGL
**************************************************************************************************/
void RenderManager::startUp(void) {
	// Initialize a new window
	_window = new Window();
	_window->startUp(L"SMURFS Engine", 640, 480, 16);

	glShadeModel(GL_SMOOTH);	// Enables smooth shading
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);	// Set a black background
	glClearDepth(1.0f);		// Depth buffer setup
	glEnable(GL_DEPTH_TEST);	// Enable depth testing
	glDepthFunc(GL_LEQUAL);	// The type of depth test
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);			// Really Nice Perspective Calculations
}

/**************************************************************************************************
* Shutdown
**************************************************************************************************/
void RenderManager::shutDown(void) {
	// Destroy the window
	_window->shutDown();
	delete _window;
}

/**************************************************************************************************
* Get the singleton instance
**************************************************************************************************/
RenderManager& RenderManager::getSingleton(void) { 
	assert(singleton);
	return *singleton;
}

/**************************************************************************************************
* Get the singleton pointer
**************************************************************************************************/
RenderManager* RenderManager::getSingletonPtr(void) {
	return singleton;
}

/**************************************************************************************************
* Render the scene
**************************************************************************************************/
void RenderManager::renderScene(void) {
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// Clear the screen

	// Draw to the screen
	std::vector<Mesh*>::iterator start = drawList.begin();
	std::vector<Mesh*>::iterator end = drawList.end();
	for(std::vector<Mesh*>::iterator itr = start; itr != end; ++itr) {
		// Position The Cubes On The Screen
		glLoadIdentity();
		glTranslatef((GLfloat) (*itr)->screenCoords.x, (*itr)->screenCoords.y, (*itr)->screenCoords.z);
		glRotatef(15.0f, 1.0f, 0.0f, 0.0f);

		if((*itr)->type == PYRAMID || (*itr)->type == SPHERE)
			glBegin(GL_TRIANGLES);
		else
			glBegin(GL_QUADS);

		// Draw the mesh
		for(unsigned int i = 0; i < (*itr)->vertices.size(); i++) {
			Vector3 color = (*itr)->colors[i];
			Vector3 position = (*itr)->vertices[i];
			glColor3f(color.x, color.y, color.z);
			glVertex3f(position.x, position.y, position.z);
		}

		glEnd();
	}

	SwapBuffers(_window->getHDC());
}

/**************************************************************************************************
* Add an object to the scene
**************************************************************************************************/
void RenderManager::addToScene(Mesh* obj) {
	drawList.push_back(obj);
}

/**************************************************************************************************
* Remove an object from the scene
**************************************************************************************************/
void RenderManager::removeFromScene(GLuint id) {
}

/**************************************************************************************************
* Returns the quadratic
**************************************************************************************************/
GLUquadricObj* RenderManager::getQuadratic(void) {
	return quadratic;
}